home *** CD-ROM | disk | FTP | other *** search
/ START Magazine / START VOL 4 NO 10.st / info_src.arc / REC.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1990-02-01  |  56.9 KB  |  1,709 lines

  1. {InfoBaseST by James W. Maki (c) Copyright 1990 by Antic Publishing, Inc.}
  2. {$M+}
  3. {$E+}
  4.  
  5. Program Record_Module;
  6.  
  7.       {$I A:GEMSUBS.PAS }
  8.       {$I A:AUXSUBS.PAS }
  9.  
  10.  Const
  11.       {$I B:MOD_CONS.PAS }
  12.  
  13.  Type
  14.       {$I B:MOD_TYPE.PAS }
  15.  
  16.  Var
  17.       {$I B:MOD_VAR.PAS }
  18.  
  19. {   *********************  External  ***********************************   }
  20.   procedure CalcOffset(    FirstRec, CurRec : ScrPtr ; 
  21.                        Var Offset : short_integer ) ;
  22.      External ;
  23.  
  24.   procedure FillString(Var SourceStr : Str50 ; FillChar : char ) ;
  25.      External ;
  26.  
  27.   procedure DrawDesign ;
  28.      External ;
  29.  
  30.   procedure DrawScreen( CurRec : ScrPtr ) ;
  31.      External ;
  32.  
  33.   procedure DrawRecord(CurRec : DataPtr ) ;
  34.      External ;
  35.  
  36.   procedure Do_Redraw(msg : Message_Buffer ) ;
  37.      External ;
  38.  
  39.   procedure GetStr(CurRec : DataPtr ; Var DisplayStr : Str255 ;
  40.                    Start, Size : short_integer ) ;
  41.      External ;
  42.  
  43.   procedure DetCurRec(    D_CurRec : DataStorePtr ;
  44.                       Var CurRec   : DataStorePtr ;  
  45.                       Var Location : short_integer ) ;
  46.      External ;
  47.  
  48.   procedure ModifyStr(CurRec : DataPtr ; Location : short_integer ; 
  49.                       InChar : char) ;
  50.      External ;
  51.  
  52.   procedure DisposeRecs(Var FirstRec, CurRec, LastRec : ScrPtr ) ;
  53.      External ;
  54.  
  55.   procedure DisposeInt(Var FirstRec, CurRec, LastRec : IntPtr ) ;
  56.      External ;
  57.  
  58.   procedure ClearRecord( CurRec : DataPtr ) ;
  59.      External ;
  60.  
  61.   procedure D_DisposeRecs(Var FirstRec, CurRec, LastRec : DataPtr ) ;
  62.      External ;
  63.  
  64.   procedure PlusMemAvail(RecSize : long_integer) ;
  65.      External ;
  66.      
  67.   procedure MinusMemAvail(RecSize : long_integer ) ;
  68.      External ;
  69.  
  70.   procedure FormatCheck( CurRec : DataPtr ) ;
  71.      External ;     
  72.  
  73.   procedure UpdateInfoLine ;
  74.      External ;
  75.  
  76.   procedure MB_Input(X_Mouse, Y_Mouse : short_integer) ;
  77.      External ;
  78.  
  79.   procedure ClrHome ;
  80.      External ;
  81.  
  82.   procedure NewCursor(ScrMode : short_integer) ;
  83.      External ;
  84.  
  85.   procedure ChangeMode( Var Mode, NewMode : short_integer ) ;
  86.      External ;
  87.  
  88.   procedure MenuOption ;
  89.      External ;
  90.  
  91.   procedure CopyRight ;
  92.      External ;
  93. {   ********************************************************************   }
  94.  
  95. { *************************************************************************
  96.      Display Verticle slider in proper position and size.
  97. ************************************************************************* }
  98.   procedure Set_VSlideSize ;
  99.  
  100.     var
  101.        SlideSize : short_integer ;
  102.  
  103.      begin     
  104.        Case Mode of
  105.         1,4 : SlideSize := 1000 ;
  106.           2 : begin
  107.                 if D_FirstRec[DataNum] <> nil then
  108.                    SlideSize := 1000 DIV TotalRec[DataNum]
  109.                 else
  110.                    SlideSize := 1000 ;
  111.               end ;
  112.           3 : begin
  113.                 if F_FirstRec <> nil then
  114.                    SlideSize := 1000 DIV F_TotalRec[DataNum]
  115.                 else
  116.                    SlideSize := 1000 ;
  117.               end ;
  118.           5 : SlideSize := 10000 DIV TotScrRec
  119.        end ;
  120.  
  121.        if SlideSize < 1 then SlideSize := 1
  122.        else
  123.           if SlideSize > 1000 then SlideSize := 1000 ;
  124.        Wind_Set(WindNum, WF_VSlSize, SlideSize, 0, 0, 0) ;
  125.      end ;
  126.  
  127. { *************************************************************************
  128.      Modify the name displayed in the title section of the GEM Window.
  129. ************************************************************************* }
  130.   procedure ModifyWName ;
  131.  
  132.     var
  133.        i,
  134.        Position : short_integer ;
  135.        FileName : array[1..2] of Window_Title ;
  136.         
  137.      begin
  138.        if S_FirstRec[ScrNum] <> nil then
  139.           FileName[1] := DefFileScr
  140.        else
  141.           FileName[1] := ' empty ' ;
  142.  
  143.        if ( D_FirstRec[ScrNum] = nil) OR
  144.           ((D_FirstRec[ScrNum] = D_LastRec[ScrNum]) AND 
  145.             NOT EditFlag[ScrNum]) then
  146.             FileName[2] := ' empty '
  147.        else
  148.           FileName[2] := DefFileDat ;
  149.        
  150.        for i := 1 to 2 do
  151.            begin
  152.              Repeat
  153.                Position := Pos(chr($5C), FileName[i]) ;
  154.                if Position > 0 then
  155.                   Delete(FileName[i], 1, Position) ;
  156.              Until Position = 0 ;
  157.  
  158.              Position := Pos(chr($2E), FileName[i]) ;
  159.              if Position > 0 then
  160.                 Delete(FileName[i], Position,
  161.                        Length(FileName[i]) - Position + 1) ;
  162.           end ;
  163.                 
  164.        WindName[1] := Concat(' Design: ', FileName[1], 
  165.                              '  Database: ', FileName[2], chr($20)) ;
  166.        Set_WName(ScrNum, WindName[1]) ;
  167.      end ;
  168.       
  169. { *************************************************************************
  170.      Define the DiskError encountered during Save and Retrieve routines.
  171. ************************************************************************* }
  172.   procedure DiskError(IO_Result : short_integer ) ;
  173.  
  174.     var
  175.        SaveStr     : Str255 ;
  176.  
  177.      begin
  178.        if IO_Result = -39 then
  179.           begin
  180.             AlertStr := '[1][ Insufficient Disk Space |' ;
  181.             AlertStr := Concat(AlertStr,'       to Save File | ]') ;
  182.           end 
  183.        else
  184.           if IO_Result = -33 then
  185.              AlertStr := '[1][ File Not Found | ]'
  186.           else
  187.              if IO_Result = 9 then
  188.                 AlertStr := '[1][ File Name Error | ]'
  189.              else
  190.                 if IO_Result = 1 then
  191.                    begin
  192.                      AlertStr := '[1][  Incorrect File Structure |' ;
  193.                      AlertStr := Concat(AlertStr, '      Encountered |') ;
  194.                      AlertStr := Concat(AlertStr,' During File Operation | ]') ;
  195.                    end
  196.                 else
  197.                    begin
  198.                      WriteV(SaveStr, IO_Result) ;
  199.                      AlertStr := '[1][  Disk Access Error ' ;
  200.                      AlertStr := Concat(AlertStr, SaveStr, ' |') ;
  201.                      AlertStr := Concat(AlertStr,' During File Operation | ]') ;
  202.                    end ;
  203.        AlertStr := Concat(AlertStr, '[ Continue ]') ;
  204.        Result := Do_Alert(AlertStr,1) ;
  205.      end ;
  206.  
  207. { *************************************************************************
  208.      AddARec adds a new ScrPtr record to the list.  It starts at the
  209.      position of CurRec (usually the first record) and searches until
  210.      the end of the list is found.  At that point, a new record is created
  211.      and the appropriate information stored.
  212. ************************************************************************* }
  213.   procedure AddARec(Var FirstRec, CurRec, LastRec, ScrRec : ScrPtr ;
  214.                         TitleStr : Str255 ;
  215.                         XCur, YCur, Size : short_integer ;
  216.                         DataType : char ; ScrNum : short_integer ) ;
  217.  
  218.     var
  219.        T_Offset : short_integer ;
  220.       
  221.      begin
  222.        if ScrRec = nil then
  223.           begin
  224.             MinusMemAvail(ScrRecSize) ;
  225.             new(ScrRec) ;
  226.  
  227.             ScrRec^.Next := nil ;
  228.             ScrRec^.Prev := LastRec ;
  229.             LastRec := ScrRec ;
  230.             CurRec  := ScrRec ;
  231.  
  232.             if FirstRec = nil then 
  233.                begin
  234.                  FirstRec := ScrRec ;
  235.                  FirstRec^.Prev := nil ;
  236.                end ;
  237.  
  238.             ScrRec^.LabelStr := TitleStr ;
  239.             ScrRec^.DataType := DataType ;
  240.             ScrRec^.X        := XCur ;
  241.             ScrRec^.Y        := YCur ;
  242.             ScrRec^.Size     := Size ;
  243.             ScrRec^.XInPos   := 0 ;
  244.             ScrRec^.XPos     := XCur + Length(TitleStr) + 3 ; 
  245.             ScrRec^.YPos     := YCur ;
  246.  
  247.             CalcOffset(FirstRec, ScrRec, T_Offset ) ;
  248.             ScrRec^.Offset   := T_Offset ;
  249.           end
  250.        else
  251.           AddARec(FirstRec, CurRec, LastRec, ScrRec^.Next, TitleStr, 
  252.                   XCur, YCur, Size, DataType, ScrNum ) ;
  253.      end ;
  254.  
  255. { *************************************************************************
  256.      DS_AddARec adds a new DataStorePtr record.
  257. ************************************************************************* }
  258.   procedure DS_AddARec(Var CurRec : DataStorePtr ; 
  259.                            Size, DataNum : short_integer ) ;
  260.  
  261.      begin
  262.        if Size > 0 then
  263.           begin
  264.             Size := Size - 1 ;
  265.             MinusMemAvail(DataRecSize) ;
  266.             new(CurRec) ;
  267.             if DataNum = Report then
  268.                FillString(CurRec^.DataStr, chr($20))
  269.             else
  270.                FillString(CurRec^.DataStr, chr(1)) ;
  271.             DS_AddARec(CurRec^.Next, Size, DataNum) ;
  272.           end ;
  273.      end ;
  274.  
  275.  
  276. { *************************************************************************
  277.      D_AddARec sets up the DataPtr record that points to the first
  278.      Data Record and then calls DS_AddARec to set up the necessary 
  279.      number of DataStorage records as a linked list.
  280. ************************************************************************* }
  281.   procedure D_AddARec(Var FirstRec, CurRec, LastRec, DataRec  : DataPtr ; 
  282.                           Size, DataNum : short_integer ) ;
  283.    
  284.      begin
  285.        if DataRec = nil then
  286.           begin
  287.             MinusMemAvail(PtrRecSize) ;
  288.             new(DataRec) ;
  289.  
  290.             DataRec^.Next := nil ;
  291.             DataRec^.Prev := LastRec ;
  292.             LastRec := DataRec ;
  293.             CurRec := DataRec ;
  294.  
  295.             if FirstRec = nil then 
  296.                begin
  297.                  FirstRec := DataRec ;
  298.                  FirstRec^.Prev := nil ;
  299.                end ;
  300.  
  301.             DataRec^.OrderMore := nil ;
  302.             DataRec^.OrderLess := nil ;
  303.             DS_AddARec(DataRec^.Data, Size, DataNum) ;
  304.             TotalRec[DataNum] := TotalRec[DataNum] + 1 ;
  305.           end
  306.        else
  307.           D_AddARec(FirstRec,CurRec,LastRec,DataRec^.Next,Size,DataNum) ;
  308.      end ;
  309.  
  310. { *************************************************************************
  311.      InputeDataRec determines the number of Str50 records that will be
  312.      required and then creates the necessary records by calling
  313.      D_AddARec. Used for loading a pre-existing Database from disk.
  314. ************************************************************************* }
  315.   procedure InputDataRec(DataNum : short_integer) ;
  316.    
  317.     var
  318.        TotalSize,
  319.        NumRecs    : short_integer ;
  320.    
  321.      begin
  322.        TotalSize := S_LastRec[DataNum]^.Offset + S_LastRec[DataNum]^.Size ;
  323.        NumRecs   := (TotalSize DIV 50) + 1 ;
  324.        D_AddARec(D_FirstRec[DataNum], D_CurrentRec[DataNum],
  325.                  D_LastRec[DataNum], D_LastRec[DataNum], NumRecs, DataNum) ;
  326.      end ;
  327.  
  328. { *************************************************************************
  329.      CreateDataRec determines the number of Str50 records that will be
  330.      required and then creates the necessary records by calling
  331.      D_AddARec.
  332. ************************************************************************* }
  333.   procedure CreateDataRec(DataNum : short_integer) ;
  334.  
  335.     var
  336.        Location : short_integer ;
  337.        ScrRec   : ScrPtr ;
  338.    
  339.      begin
  340.        InputDataRec(DataNum) ;
  341.        ScrRec := S_FirstRec[DataNum] ;
  342.        WHILE ScrRec <> nil do
  343.          BEGIN
  344.            if ScrRec^.DataType = 'F' then
  345.               begin
  346.                 Location := ScrRec^.Offset ;
  347.                 ModifyStr(D_CurrentRec[DataNum], Location, chr($24)) ;
  348.                 DrawRecord(D_CurrentRec[DataNum]) ;
  349.               end ;
  350.             ScrRec := ScrRec^.Next ;
  351.          END ;
  352.        Set_VSlideSize ;
  353.      end ;
  354.  
  355. { *************************************************************************
  356.      Adds to the list of integers which describe the order of a
  357.      Merge function of dissimilar database and design form, or
  358.      the index for search records.
  359. ************************************************************************* }
  360.   procedure Int_AddARec(Var FirstRec, CurRec, LastRec : IntPtr ; 
  361.                             Value : short_integer ) ;
  362.   
  363.      begin
  364.        if CurRec = nil then
  365.           begin
  366.             new(CurRec) ;
  367.             if FirstRec = nil then
  368.                FirstRec := CurRec ;
  369.             CurRec^.Match := Value ;
  370.             CurRec^.Next := nil ;
  371.             CurRec^.Prev := LastRec ;
  372.             LastRec := CurRec ;
  373.           end
  374.        else
  375.           Int_AddARec(FirstRec, CurRec^.Next, LastRec, Value) ;
  376.      end ;
  377.  
  378. { *************************************************************************
  379.      IncrementRec moves the D_CurrentRec pointer to the next or previous
  380.      record of the linked list depending on the value of Value.
  381. ************************************************************************* }
  382.   procedure IncrementRec(Var  CurRec : DataPtr ; Value : short_integer ;
  383.                               DrawFlag : boolean ) ;
  384.  
  385.     var
  386.        i,
  387.        Count,
  388.        NewCount,
  389.        OldCount : short_integer ;
  390.        DrawRec  : boolean ;
  391.        ScrRec   : ScrPtr ;
  392.  
  393.      procedure ChangeRec(Value : short_integer) ;
  394.  
  395.         begin
  396.           RecNo[DataNum] := RecNo[DataNum] + Value ;
  397.           DrawRec := true ;
  398.         end ;
  399.  
  400.      procedure I_NextRec ;
  401.      
  402.         begin
  403.           CurRec := CurRec^.Next ;
  404.           ChangeRec(Value) ;
  405.         end ;
  406.  
  407.      procedure I_PrevRec ;
  408.  
  409.         begin
  410.           CurRec := CurRec^.Prev ;
  411.           ChangeRec(Value) ;
  412.        end ;
  413.  
  414.  
  415.      procedure S_NextRec ;
  416.  
  417.        var
  418.           i : short_integer ;
  419.  
  420.         begin
  421.           OldCount := F_CurRec^.Match ;
  422.           F_CurRec := F_CurRec^.Next ;
  423.           F_RecNo[DataNum] := F_RecNo[DataNum] + 1 ;
  424.           NewCount := F_CurRec^.Match ;
  425.           Count := NewCount - OldCount ;
  426.           for i := 1 to Count do
  427.               CurRec := CurRec^.Next ;
  428.           RecNo[DataNum] := F_CurRec^.Match ;
  429.           DrawRec := true ;
  430.         end ;
  431.  
  432.      procedure S_PrevRec ;
  433.  
  434.        var
  435.           i : short_integer ;
  436.  
  437.         begin
  438.           OldCount := F_CurRec^.Match ;
  439.           F_CurRec := F_CurRec^.Prev ;
  440.           F_RecNo[DataNum] := F_RecNo[DataNum] - 1 ;
  441.           NewCount := F_CurRec^.Match ;
  442.           Count := OldCount - NewCount ;
  443.           for i := 1 to Count do
  444.               CurRec := CurRec^.Prev ;
  445.           RecNo[DataNum] := F_CurRec^.Match ;
  446.           DrawRec := true ;
  447.         end ;
  448.  
  449.      begin
  450.        if CurRec <> nil then
  451.           begin
  452.              DrawRec := false ;
  453.              FormatCheck(CurRec) ;
  454.              Case Mode of
  455.                2 : if (Value = 1) AND (CurRec^.Next <> nil) then
  456.                       I_NextRec
  457.                    else
  458.                       if (Value = -1) AND (CurRec^.Prev <> nil) then
  459.                          I_PrevRec ;
  460.                3 : if NOT SearchFlag then
  461.                       begin
  462.                         if (Value = 1) AND (F_CurRec^.Next <> nil) then
  463.                            S_NextRec
  464.                         else
  465.                            if (Value = -1) AND (F_CurRec^.Prev <> nil) then
  466.                               S_PrevRec ;
  467.                       end ;
  468.                5 : if F_FirstRec <> nil then
  469.                       begin
  470.                         if F_CurRec^.Next <> nil then
  471.                            S_NextRec
  472.                         else
  473.                            CurRec := nil ;
  474.                       end 
  475.                    else
  476.                       begin
  477.                         if CurRec^.Next <> nil then
  478.                            I_NextRec
  479.                         else
  480.                            CurRec := nil ;
  481.                       end ;
  482.              end ;
  483.  
  484.              if DrawRec AND DrawFlag AND (Mode <> 5) then
  485.                 begin
  486.                   UpdateFlag := true ; ;
  487.                   ClrHome ;
  488.                   DrawRecord(CurRec) ;
  489.                 end ;
  490.           end ;
  491.      end ;
  492.  
  493.  
  494. { *************************************************************************
  495.      Move to the First DataRec record if in Input Mode or the first Search
  496.      record if in Record Mode.
  497. ************************************************************************* }
  498.   procedure GoToFirst( Var CurRec : DataPtr ; DrawFlag : boolean ) ;
  499.  
  500.     var
  501.        DrawRec : boolean ;
  502.        i       : short_integer ;
  503.  
  504.      begin
  505.        DrawRec := false ;
  506.        if CurRec <> nil then
  507.           begin
  508.              FormatCheck(CurRec) ;
  509.              Case Mode of
  510.                2 : if CurRec <> D_FirstRec[DataNum] then
  511.                       begin
  512.                         CurRec := D_FirstRec[DataNum] ;
  513.                         RecNo[DataNum] := 1 ;
  514.                         DrawRec := true ;
  515.                       end ;
  516.                3 : if NOT SearchFlag AND (F_CurRec <> F_FirstRec) then
  517.                       begin
  518.                         F_CurRec := F_FirstRec ;
  519.                         F_RecNo[DataNum] := 1 ;
  520.                         CurRec := D_FirstRec[DataNum] ;
  521.                         for i := 2 to F_CurRec^.Match do
  522.                             CurRec := CurRec^.Next ;
  523.                         RecNo[DataNum] := i - 1 ;
  524.                         DrawRec := true ;
  525.                       end ;
  526.              end ;
  527.           
  528.              if DrawRec AND DrawFlag then
  529.                 begin
  530.                   UpdateFlag := true ; ;
  531.                   ClrHome ;
  532.                   DrawRecord(CurRec) ;
  533.                 end ;
  534.           end ;
  535.      end ;
  536.      
  537. { *************************************************************************
  538.      Go to the last record.  Different for Search and Input Mode.
  539. ************************************************************************* }
  540.   procedure GoToLast(Var CurRec : DataPtr ; DrawFlag : boolean) ;
  541.  
  542.     var
  543.        i       : short_integer ;
  544.        DrawRec : boolean ;
  545.        ScrRec  : ScrPtr ;
  546.  
  547.      begin
  548.        DrawRec := false ;
  549.        if CurRec <> nil then
  550.           begin
  551.              FormatCheck(CurRec) ;
  552.              Case Mode of
  553.                2 : if CurRec <> D_LastRec[DataNum] then
  554.                       begin
  555.                         CurRec := D_LastRec[DataNum] ;
  556.                         RecNo[DataNum] := TotalRec[DataNum] ;
  557.                         DrawRec := true ;
  558.                       end ;
  559.                3 : if NOT SearchFlag AND (F_CurRec <> F_LastRec) then
  560.                       begin
  561.                         F_CurRec := F_LastRec ;
  562.                         F_RecNo[DataNum] := F_TotalRec[DataNum] ;
  563.                         CurRec := D_FirstRec[DataNum] ;
  564.                         for i := 2 to F_CurRec^.Match do
  565.                             CurRec := CurRec^.Next ;
  566.                         RecNo[DataNum] := i - 1 ;
  567.                         DrawRec := true ;
  568.                       end ;
  569.              end ;
  570.  
  571.              if DrawRec AND DrawFlag then
  572.                 begin
  573.                   UpdateFlag := true ; ;
  574.                   ClrHome ;
  575.                   DrawRecord(CurRec) ;
  576.                 end ;
  577.           end ;
  578.      end ;
  579.  
  580. { *************************************************************************
  581.      DeleteARec removes a field from the current record design.
  582. ************************************************************************* }
  583.   procedure DeleteARec(CurRec : ScrPtr) ;
  584.  
  585.     var
  586.        NextRec : ScrPtr ;
  587.  
  588.      begin
  589.        if CurRec^.DataType = 'H' then
  590.           NextRec := CurRec^.Next
  591.        else
  592.           NextRec := nil ;
  593.        if (CurRec = S_FirstRec[ScrNum]) AND 
  594.           (CurRec = S_LastRec[ScrNum]) then
  595.           begin
  596.             { Delete Only Record }
  597.             S_FirstRec[ScrNum]   := nil ;
  598.             S_LastRec[ScrNum]    := nil ;
  599.             S_CurrentRec[ScrNum] := nil ;
  600.           end
  601.        else
  602.           if CurRec = S_FirstRec[ScrNum] then
  603.              { Delete First Record  }
  604.              begin
  605.                S_FirstRec[ScrNum]   := CurRec^.Next ;
  606.                CurRec^.Next^.Prev   := nil ;
  607.                S_CurrentRec[ScrNum] := S_FirstRec[ScrNum] ;
  608.              end
  609.           else
  610.              if CurRec = S_LastRec[ScrNum] then
  611.                 { Delete Last Record }
  612.                 begin
  613.                   S_LastRec[ScrNum]    := CurRec^.Prev ;
  614.                   CurRec^.Prev^.Next   := nil ;
  615.                   S_CurrentRec[ScrNum] := S_LastRec[ScrNum] ;
  616.                 end
  617.              else
  618.                 { Delete a Middle Record }
  619.                 begin
  620.                   CurRec^.Prev^.Next   := CurRec^.Next ;
  621.                   CurRec^.Next^.Prev   := CurRec^.Prev ;
  622.                   S_CurrentRec[ScrNum] := CurRec^.Next ;
  623.                 end ;
  624.        Dispose(CurRec) ;
  625.        PlusMemAvail(ScrRecSize) ;
  626.        if NextRec <> nil then
  627.           DeleteARec(NextRec) ;
  628.      end ;
  629.  
  630. { *************************************************************************
  631.      DisposeData Disposes the DataStore records associated with
  632.      the DataPtr record CurRec.  DispRec is a saved pointer while
  633.      NextRec stores the location of the next pointer in the linked
  634.      list of data store locations.
  635. ************************************************************************* }
  636.   procedure DisposeData( CurRec : DataPtr ) ;
  637.  
  638.     var
  639.        DispRec,
  640.        NextRec : DataStorePtr ;
  641.       
  642.      begin
  643.        NextRec := CurRec^.Data ;
  644.        While NextRec <> nil do
  645.           begin
  646.             DispRec := NextRec ;
  647.             NextRec := NextRec^.Next ;
  648.             Dispose(DispRec) ;
  649.             PlusMemAvail(DataRecSize) ;
  650.           end ;
  651.      end ;
  652.  
  653. { *************************************************************************
  654.      Int_DeleteARec removes a Integer Record from the current list.
  655.      FOR SEARCH MODE ONLY!!!
  656. ************************************************************************* }
  657.   procedure Int_DeleteARec(    CurRec : IntPtr ; 
  658.                            Var F_DataRec, DataRec : DataPtr) ;
  659.  
  660.     var
  661.        NewMode,
  662.        i       : short_integer ;
  663.        ModRec  : IntPtr ;
  664.  
  665.      begin
  666.        ModRec := CurRec ;
  667.        While ModRec <> nil do
  668.           begin
  669.             ModRec^.Match := ModRec^.Match - 1 ;
  670.             ModRec := ModRec^.Next ;
  671.           end ;
  672.           
  673.        F_TotalRec[DataNum] := F_TotalRec[DataNum] - 1 ;
  674.        if (CurRec = F_FirstRec) AND 
  675.           (CurRec = F_LastRec) then
  676.           begin
  677.             { Delete Only Record }
  678.             F_FirstRec := nil ;
  679.             F_LastRec  := nil ;
  680.             F_CurRec   := nil ;
  681.             NewMode := 2 ;
  682.             ChangeMode(Mode, NewMode) ;
  683.             MenuOption ;
  684.           end
  685.        else
  686.           if CurRec = F_FirstRec then
  687.              { Delete First Record  }
  688.              begin
  689.                F_FirstRec := CurRec^.Next ;
  690.                CurRec^.Next^.Prev  := nil ;
  691.                F_CurRec := F_FirstRec ;
  692.              end
  693.           else
  694.              if CurRec = F_LastRec then
  695.                 { Delete Last Record }
  696.                 begin
  697.                   F_LastRec := CurRec^.Prev ;
  698.                   CurRec^.Prev^.Next := nil ;
  699.                   F_CurRec := F_LastRec ;
  700.                   F_RecNo[DataNum] := F_RecNo[DataNum] - 1 ;
  701.                 end
  702.              else
  703.                 { Delete a Middle Record }
  704.                 begin
  705.                   CurRec^.Prev^.Next   := CurRec^.Next ;
  706.                   CurRec^.Next^.Prev   := CurRec^.Prev ;
  707.                   F_CurRec := CurRec^.Next ;
  708.                 end ;
  709.  
  710.        Dispose(CurRec) ;
  711.        DataRec := F_DataRec ;
  712.        RecNo[DataNum] := 1 ;
  713.        if F_CurRec <> nil then
  714.           begin
  715.             for i := 2 to F_CurRec^.Match do
  716.                 DataRec := DataRec^.Next ;
  717.             RecNo[DataNum] := i - 1 ;
  718.           end ;
  719.      end ;
  720.  
  721. { *************************************************************************
  722.      Dispose of the DataPtr record and call the routine to Dispose of
  723.      the related DataStoreRecords.
  724. ************************************************************************* }
  725.   procedure DispDataRec( CurRec : DataPtr ) ;
  726.  
  727.      begin
  728.        if DelItem <> nil then
  729.           begin
  730.             DisposeData(DelItem) ;
  731.             Dispose(DelItem) ;
  732.             PlusMemAvail(PtrRecSize) ;
  733.           end ;
  734.           
  735.        TotalRec[DataNum] := TotalRec[DataNum] - 1 ;
  736.        DelItem := CurRec ;
  737.      end ;
  738.  
  739. { *************************************************************************
  740.      DS_DeleteARec removes a Record from the current data base.
  741. ************************************************************************* }
  742.   procedure DS_DeleteARec(CurRec : DataPtr) ;
  743.  
  744.      begin
  745.        DispDataRec(CurRec) ;
  746.        if (CurRec = D_FirstRec[DataNum]) AND 
  747.           (CurRec = D_LastRec[DataNum]) then
  748.           begin
  749.             { Delete Only Record }
  750.             D_FirstRec[DataNum]   := nil ;
  751.             D_LastRec[DataNum]    := nil ;
  752.             D_CurrentRec[DataNum] := nil ;
  753.             CreateDataRec(DataNum) ;
  754.           end
  755.        else
  756.           if CurRec = D_FirstRec[DataNum] then
  757.              { Delete First Record  }
  758.              begin
  759.                D_FirstRec[DataNum]   := CurRec^.Next ;
  760.                CurRec^.Next^.Prev   := nil ;
  761.                D_CurrentRec[DataNum] := D_FirstRec[DataNum] ;
  762.                RecNo[DataNum] := 1 ;
  763.              end
  764.           else
  765.              if CurRec = D_LastRec[DataNum] then
  766.                 { Delete Last Record }
  767.                 begin
  768.                   D_LastRec[DataNum]    := CurRec^.Prev ;
  769.                   CurRec^.Prev^.Next   := nil ;
  770.                   D_CurrentRec[DataNum] := D_LastRec[DataNum] ;
  771.                   RecNo[DataNum] := TotalRec[DataNum] ;
  772.                 end
  773.              else
  774.                 { Delete a Middle Record }
  775.                 begin
  776.                   CurRec^.Prev^.Next   := CurRec^.Next ;
  777.                   CurRec^.Next^.Prev   := CurRec^.Prev ;
  778.                   D_CurrentRec[DataNum] := CurRec^.Next ;
  779.                 end ;
  780.  
  781.        if (Mode = 3) AND (F_CurRec <> nil) then
  782.           Int_DeleteARec(F_CurRec, 
  783.                          D_FirstRec[DataNum], D_CurrentRec[DataNum]) ;
  784.        Set_VSlideSize ;
  785.      end ;
  786.  
  787. { *************************************************************************
  788.      Get necessary information to open a Screen Info file and
  789.      paint screen with proper form.
  790. ************************************************************************* }
  791.   procedure OpenScrnInfo( Var Flag : boolean) ;
  792.      
  793.     var
  794.        i             : short_integer ;
  795.        CurRec        : ScrPtr ;
  796.        NewRecFlag    : boolean ;
  797.        SaveIO_Result : short_integer ;
  798.  
  799.     Label
  800.        1 ;
  801.  
  802.      begin
  803.        SaveIO_Result := 1 ;
  804.        NewRecFlag := false ;
  805.        Flag := false ;
  806.        if Get_In_File(DefPathScr, DefFileScr) then
  807.           begin
  808.             IO_Check(false) ;
  809.  
  810.             Reset(ScrnStore,DefFileScr) ;
  811.             SaveIO_Result := IO_Result ;
  812.             if SaveIO_Result <> 0 then GoTo 1 ;
  813.  
  814.             MinusMemAvail(ScrRecSize) ;
  815.             new(CurRec) ;
  816.             NewRecFlag := true ;
  817.  
  818.             Read(ScrnStore, CurRec^) ;
  819.             SaveIO_Result := IO_Result ;
  820.             if SaveIO_Result <> 0 then GoTo 1 ;
  821.             if CurRec^.LabelStr <> 'ScreenDesign' then
  822.                begin
  823.                  SaveIO_Result := 1 ;
  824.                  GoTo 1 ;
  825.                end ;
  826.  
  827.             DisposeRecs(S_FirstRec[ScrNum], S_CurrentRec[ScrNum], 
  828.                         S_LastRec[ScrNum] ) ;
  829.  
  830.             for i := 1 to 4 do
  831.                 begin
  832.                   Read(ScrnStore, CurRec^) ;
  833.                   SaveIO_Result := IO_Result ;
  834.                   if SaveIO_Result <> 0 then GoTo 1 ;
  835.                   PrtInit[i] := CurRec^.LabelStr ;
  836.                   DecReal    := CurRec^.X ;
  837.                 end ;
  838.  
  839.             While NOT EOF(ScrnStore) do
  840.                begin
  841.                  Read(ScrnStore, CurRec^) ;
  842.                  SaveIO_Result := IO_Result ;
  843.                  if SaveIO_Result <> 0 then GoTo 1 ;
  844.                  AddARec(S_FirstRec[ScrNum],S_CurrentRec[ScrNum],
  845.                          S_LastRec[ScrNum], S_LastRec[ScrNum],
  846.                          CurRec^.LabelStr, CurRec^.X, CurRec^.Y, 
  847.                          CurRec^.Size, CurRec^.DataType, ScrNum)
  848.                end ;
  849.  
  850. 1 :         if SaveIO_Result <> 0 then
  851.                DiskError(SaveIO_Result) ;              
  852.                
  853.             if NewRecFlag then
  854.                begin
  855.                  Dispose(CurRec) ;
  856.                  PlusMemAvail(ScrRecSize) ;
  857.                end ;
  858.  
  859.             if SaveIO_Result = 0 then
  860.                begin
  861.                  CurRec := S_FirstRec[ScrNum] ;
  862.                  ModifyWName ;
  863.                  D_EditFlag[ScrNum] := False ;
  864.                  Flag := true
  865.                end 
  866.             else
  867.                Flag := false ;
  868.  
  869.             Close(ScrnStore) ;
  870.             DrawScreen( S_FirstRec[ScrNum] ) ;
  871.             ShortDraw := true ;
  872.  
  873.             IO_Check(true) ;
  874.           end ;
  875.      end ;
  876.  
  877. { *************************************************************************
  878.      Save the current screen form design to a disk file.
  879. ************************************************************************* }
  880.   procedure SaveScrnInfo ;
  881.      
  882.     var
  883.        i           : short_integer ;
  884.        CurRec      : ScrPtr ;
  885.        BakFile     : text ;
  886.        BakFileName : Path_Name ;
  887.        SaveIO_Result,
  888.        Position    : short_integer ;
  889.  
  890.     Label
  891.        1 ;
  892.  
  893.      begin
  894.        if Get_In_File(DefPathScr, DefFileScr) then
  895.           begin
  896.             IO_Check(false) ;
  897.             Reset(ScrnStore, DefFileScr) ;
  898.             SaveIO_Result := IO_Result ;
  899.             if SaveIO_Result = 0 then
  900.                begin
  901.                  BakFileName := DefFileScr ;
  902.                  Position := Pos('.SCR', BakFileName) ;
  903.                  if Position > 0 then
  904.                     begin
  905.                       Delete(BakFileName, Position, 4) ;
  906.                       BakFileName := Concat(BakFileName, '.BSC') ;
  907.                     end 
  908.                  else
  909.                     BakFileName := 'A:SCREEN.BSC' ;
  910.                  
  911.                   Reset(BakFile,BakFileName) ;
  912.                   SaveIO_Result := IO_Result ;
  913.                   if (SaveIO_Result <> -33) AND 
  914.                      (SaveIO_Result <> 0) then GoTo 1 ;
  915.                   Rename(ScrnStore, BakFile) ;
  916.                   SaveIO_Result := IO_Result ;
  917.                   if SaveIO_Result <> 0 then GoTo 1 ;
  918.                end ;
  919.  
  920.             Rewrite(ScrnStore, DefFileScr) ;
  921.             SaveIO_Result := IO_Result ;
  922.             if SaveIO_Result <> 0 then GoTo 1 ;
  923.  
  924.             New(CurRec) ;
  925.             CurRec^.LabelStr := 'ScreenDesign' ;
  926.  
  927.             Write(ScrnStore, CurRec^) ;
  928.             SaveIO_Result := IO_Result ;
  929.             if SaveIO_Result <> 0 then GoTo 1 ;
  930.  
  931.             for i := 1 to 4 do
  932.                 begin
  933.                   CurRec^.LabelStr := PrtInit[i] ;
  934.                   CurRec^.X := DecReal ;
  935.                   Write(ScrnStore, CurRec^) ;
  936.                   SaveIO_Result := IO_Result ;
  937.                   if SaveIO_Result <> 0 then GoTo 1 ;
  938.                 end ;
  939.             Dispose(CurRec) ;
  940.             
  941.             CurRec := S_FirstRec[ScrNum] ;
  942.  
  943.             While CurRec <> nil do
  944.                begin
  945.                  Write(ScrnStore, CurRec^) ;
  946.                  SaveIO_Result := IO_Result ;
  947.                  if SaveIO_Result <> 0 then GoTo 1 ;
  948.                  CurRec := CurRec^.Next ;
  949.                end ;
  950.  
  951. 1 :         if SaveIO_Result <> 0 then
  952.                DiskError(SaveIO_Result) ;              
  953.                
  954.             Close(ScrnStore) ;
  955.             IO_Check(true) ;
  956.             ModifyWName ;
  957.             D_EditFlag[ScrNum] := False ;
  958.           end ;
  959.      end ;
  960.  
  961. { *************************************************************************
  962.      Save the current database to the disk in order.
  963. ************************************************************************* }
  964.   procedure SaveDataBase ;
  965.  
  966.     var
  967.        CurRec      : DataPtr ;
  968.        ScrRec      : ScrPtr ;
  969.        DisplayStr  : Str255 ;
  970.        SaveFv      : text ;
  971.        BakFile     : text ;
  972.        BakFileName : Path_Name ;
  973.        i,
  974.        SaveIO_Result,
  975.        Position    : short_integer ;
  976.        F_SaveRec   : IntPtr ;
  977.        SaveRecNo   : short_integer ;
  978.        
  979.      Label
  980.        1 ;
  981.  
  982.      begin
  983.        if F_FirstRec <> nil then
  984.           begin
  985.             F_SaveRec := F_CurRec ;
  986.             SaveRecNo := F_RecNo[DataNum] ;
  987.           end ;
  988.        if Get_In_File(DefPathDat, DefFileDat) then
  989.           begin
  990.             IO_Check(false) ;
  991.             Reset(SaveFv, DefFileDat) ;
  992.             SaveIO_Result := IO_Result ;
  993.             if SaveIO_Result = 0 then 
  994.                begin
  995.                  BakFileName := DefFileDat ;
  996.                  Position := Pos('.DAT', BakFileName) ;
  997.                  if Position > 0 then
  998.                     begin
  999.                       Delete(BakFileName, Position, 4) ;
  1000.                       BakFileName := Concat(BakFileName, '.BDT') ;
  1001.                     end 
  1002.                  else
  1003.                     BakFileName := 'A:DATA.BSC' ;
  1004.             
  1005.                  Reset(BakFile,BakFileName) ;
  1006.                  SaveIO_Result := IO_Result ;
  1007.                  if (SaveIO_Result <> -33) AND 
  1008.                     (SaveIO_Result <> 0) then GoTo 1 ;
  1009.                  Rename(SaveFv, BakFile) ;
  1010.                  SaveIO_Result := IO_Result ;
  1011.                  if SaveIO_Result <> 0 then GoTo 1 ;
  1012.                end ;  
  1013.                
  1014.             Rewrite(SaveFv, DefFileDat) ;
  1015.             SaveIO_Result := IO_Result ;
  1016.             if SaveIO_Result <> 0 then GoTo 1 ;
  1017.             
  1018.             Writeln(SaveFv, 'DataBase') ;
  1019.             SaveIO_Result := IO_Result ;
  1020.             if SaveIO_Result <> 0 then GoTo 1 ;
  1021.             
  1022.             ScrRec := S_FirstRec[ScrNum] ;
  1023.             While ScrRec <> nil do
  1024.                begin
  1025.                  Writeln(SaveFv, ScrRec^.LabelStr) ;
  1026.                  SaveIO_Result := IO_Result ;
  1027.                  if SaveIO_Result <> 0 then GoTo 1 ;
  1028.                  
  1029.                  Writeln(SaveFv, ScrRec^.DataType) ;
  1030.                  SaveIO_Result := IO_Result ;
  1031.                  SaveIO_Result := IO_Result ;
  1032.                  if SaveIO_Result <> 0 then GoTo 1 ;
  1033.                  
  1034.                  WriteV(DisplayStr, ScrRec^.Size) ;
  1035.                  SaveIO_Result := IO_Result ;
  1036.                  if SaveIO_Result <> 0 then GoTo 1 ;
  1037.                  Writeln(SaveFv, DisplayStr) ;
  1038.                  SaveIO_Result := IO_Result ;
  1039.                  if SaveIO_Result <> 0 then GoTo 1 ;
  1040.                  ScrRec := ScrRec^.Next ;
  1041.                end ;
  1042.             
  1043.             Writeln(SaveFv, chr($01)) ;
  1044.             SaveIO_Result := IO_Result ;
  1045.             if SaveIO_Result <> 0 then GoTo 1 ;
  1046.              
  1047.             CurRec := D_FirstRec[DataNum] ;
  1048.             F_CurRec := nil ;
  1049.             if Mode = 3 then
  1050.                GoToFirst(CurRec, false) ;
  1051.                   
  1052.             While CurRec <> nil do
  1053.                begin
  1054.                  ScrRec := S_FirstRec[ScrNum] ;
  1055.                  While ScrRec <> nil do
  1056.                     begin
  1057.                       GetStr(CurRec, DisplayStr, 
  1058.                              ScrRec^.Offset, ScrRec^.Size ) ;
  1059.                       Writeln(SaveFv, DisplayStr) ;
  1060.                       SaveIO_Result := IO_Result ;
  1061.                       if SaveIO_Result <> 0 then GoTo 1 ;
  1062.                       ScrRec := ScrRec^.Next ;
  1063.                     end ;
  1064.                      
  1065.                  if Mode = 3 then
  1066.                     begin
  1067.                       if F_CurRec^.Next = nil then
  1068.                          CurRec := nil
  1069.                       else
  1070.                          IncrementRec(CurRec, 1, false) ;
  1071.                     end
  1072.                  else
  1073.                     CurRec := CurRec^.Next ;
  1074.                end ;
  1075.             
  1076. 1 :         if SaveIO_Result <> 0 then
  1077.                DiskError(SaveIO_Result) ;
  1078.                
  1079.             Close(SaveFv) ;
  1080.             if Mode = 2 then
  1081.                ModifyWName ;
  1082.             EditFlag[ScrNum] := false ;
  1083.             if NOT ExitPrompt then
  1084.                begin
  1085.                  DrawScreen(S_FirstRec[ScrNum]) ;
  1086.                  DrawRecord(D_CurrentRec[DataNum]) ;
  1087.                  ShortDraw := true ;
  1088.                end ;
  1089.           end ;
  1090.        if F_FirstRec <> nil then
  1091.           begin
  1092.             F_CurRec := F_SaveRec ;
  1093.             F_RecNo[DataNum] := SaveRecNo ;
  1094.           end ;
  1095.      end ;
  1096. { *************************************************************************
  1097.      Prompts for information on how the data on disk is to be Merged
  1098.      with a design form in memory which are dissimilar.
  1099. ************************************************************************* }
  1100.   procedure FindMatch(DiskRec : ScrPtr ; Compare : IntPtr) ;
  1101.  
  1102.     var
  1103.        MatchRec,
  1104.        CurRec    : ScrPtr ;
  1105.        NextRec   : IntPtr ;
  1106.        i         : byte ;
  1107.        TypeStr   : array[1..2] of Str20 ;
  1108.        QuitFlag,
  1109.        Match,
  1110.        RMB_Event : boolean ;
  1111.        UpDown    : array[1..2] of byte ;
  1112.  
  1113.    const
  1114.       Down1 = 1 ;
  1115.       Down2 = 2 ;
  1116.       Up    = 0 ;
  1117.  
  1118. { *************************************************************************
  1119.      Covert the DataType to a String description.
  1120. ************************************************************************* }
  1121.      procedure DT_To_Str(DataType : char ; Var DT_Str : Str20) ;
  1122.  
  1123.        var
  1124.           i : byte ;
  1125.  
  1126.         begin
  1127.           for i := $41 to $48 do
  1128.               if chr(i) = DataType then
  1129.                  begin
  1130.                    case i of
  1131.                        $41 : DT_Str := 'String' ;
  1132.                        $42 : DT_Str := 'Boolean' ;
  1133.                        $43 : DT_Str := 'Integer' ;
  1134.                        $44 : DT_Str := 'Company' ;
  1135.                        $45 : DT_Str := 'Real' ;
  1136.                        $46 : DT_Str := 'Dollar' ;
  1137.                        $47 : DT_Str := 'Date' ;
  1138.                        $48 : DT_Str := 'Name' ;
  1139.                    end ;
  1140.                    i := $50 ;
  1141.                  end ;
  1142.         end ;
  1143.  
  1144. { *************************************************************************
  1145.      Modify the information displayed on the Info Line.
  1146. ************************************************************************* }
  1147.      procedure UpdateInfoLine ;
  1148.  
  1149.         begin
  1150.           DT_To_Str(CurRec^.DataType, TypeStr[1]) ;
  1151.           DT_To_Str(S_CurrentRec[ScrNum]^.DataType, TypeStr[2]) ;
  1152.           WriteV(FormatStr,' Disk :',TypeStr[1]:8, chr($2F), CurRec^.Size:3,
  1153.                    chr($7C):3, 'Label :':9, chr($20), CurRec^.LabelStr, 
  1154.                    chr($20):22 - Length(CurRec^.LabelStr), chr($7C):3, 
  1155.                    chr($7C), ' Design :', TypeStr[2]:8, chr($2F),
  1156.                    S_CurrentRec[ScrNum]^.Size:3) ;
  1157.           WindInfo[WindNum] := FormatStr ;
  1158.           Set_WInfo(WindNum, WindInfo[WindNum]) ;
  1159.         end ;
  1160.  
  1161. { *************************************************************************
  1162.      Determine routine selected via the dropdown menu.
  1163. ************************************************************************* }
  1164.      procedure Menu_Select( msg : Message_Buffer) ;
  1165.  
  1166.         begin
  1167.           Case msg[4] of
  1168.              11 : CopyRight ;
  1169.              27 : begin
  1170.                     QuitFlag := true ;
  1171.                     RMB_Event := true ;
  1172.                     Match     := false ;
  1173.                     While CurRec^.Next <> nil do
  1174.                        CurRec := CurRec^.Next ;
  1175.                   end ;
  1176.              37 : if CurRec^.Next <> nil then
  1177.                      begin
  1178.                        CurRec := CurRec^.Next ;
  1179.                        NextRec := NextRec^.Next ;
  1180.                      end ;
  1181.              38 : if CurRec^.Prev <> nil then
  1182.                      begin
  1183.                        CurRec := CurRec^.Prev ;
  1184.                        NextRec := NextRec^.Prev ;
  1185.                      end ;
  1186.           end ;           
  1187.  
  1188.           Menu_Normal(InfoMenu, msg[3]);
  1189.           UpdateInfoLine ;
  1190.        end;
  1191.  
  1192. { *************************************************************************
  1193.      Traffic Manager for input during disk import operations of non-equal
  1194.      files.
  1195. ************************************************************************* }
  1196.      procedure Event_Loop ;
  1197.  
  1198.        var
  1199.           GemEvent  : short_integer ;
  1200.           msg       : Message_Buffer ;
  1201.           HiByte,
  1202.           LoByte,
  1203.           Key_Input,
  1204.           B_State,
  1205.           B_Count,
  1206.           X_Mouse, 
  1207.           Y_Mouse,
  1208.           Key_State : short_integer ;
  1209.  
  1210.         begin
  1211.           Work_Rect(WindNum, x, y, w, h);
  1212.           Set_Clip(x, y, w, h);
  1213.  
  1214.           GemEvent := Get_Event(E_Button | E_Keyboard | E_Timer | E_Message,
  1215.              1, UpDown[1], 1, 1,
  1216.              true, 0, 0, 0, 0,
  1217.              true, 0, 0, 0, 0,
  1218.              msg,
  1219.              Key_Input,
  1220.              B_State, B_Count,
  1221.              X_Mouse, Y_Mouse,
  1222.              Key_State);
  1223.  
  1224.           if (GemEvent & E_Message) <> 0 then
  1225.              Case msg[0] of
  1226.                 MN_Selected : Menu_Select(msg) ;
  1227.                 WM_Redraw   : Do_Redraw(msg) ;
  1228.              end
  1229.           else
  1230.              if (GemEvent & E_Button) <> 0 then
  1231.                 begin
  1232.                   if UpDown[1] = Down1 then
  1233.                      begin
  1234.                        MB_Input(X_Mouse, Y_Mouse) ;
  1235.                        UpdateInfoLine ;
  1236.                        UpDown[1] := Up ;
  1237.                      end
  1238.                   else
  1239.                      UpDown[1] := Down1 ;
  1240.                 end
  1241.              else
  1242.                 if (GemEvent & E_Keyboard) <> 0 then
  1243.                    begin
  1244.                      HiByte  := ShR(Key_Input, 8);
  1245.                      LoByte  := ShR(ShL(Key_Input, 8),8);
  1246.                      if (HiByte = $4D) AND (LoByte = $36) then { +-Right }
  1247.                         begin
  1248.                           if CurRec^.Next <> nil then
  1249.                              begin
  1250.                                CurRec := CurRec^.Next ;
  1251.                                NextRec := NextRec^.Next ;
  1252.                              end ;
  1253.                         end
  1254.                      else
  1255.                         if (HiByte = $4B) AND (LoByte = $34) then { +-Left }
  1256.                            begin
  1257.                              if CurRec^.Prev <> nil then
  1258.                                 begin
  1259.                                   CurRec := CurRec^.Prev ;
  1260.                                   NextRec := NextRec^.Prev ;
  1261.                                 end ;
  1262.                            end
  1263.                         else
  1264.                            if (HiByte = $10) AND (LoByte = $11) then
  1265.                               begin
  1266.                                 QuitFlag := true ;
  1267.                                 RMB_Event := true ;
  1268.                                 Match     := false ;
  1269.                                 While CurRec^.Next <> nil do
  1270.                                   CurRec := CurRec^.Next ;
  1271.                               end ;
  1272.                      UpdateInfoLine ;
  1273.                    end 
  1274.                 else
  1275.                   begin
  1276.                     GemEvent := Get_Event(E_Button | E_Timer,
  1277.                        2, UpDown[2], 1, 1,
  1278.                        true, 0, 0, 0, 0,
  1279.                        true, 0, 0, 0, 0,
  1280.                        msg,
  1281.                        Key_Input,
  1282.                        B_State, B_Count,
  1283.                        X_Mouse, Y_Mouse,
  1284.                        Key_State);
  1285.                     
  1286.                     if (GemEvent & E_Button) <> 0 then
  1287.                        if UpDown[2] = Down2 then
  1288.                           UpDown[2] := Up
  1289.                        else
  1290.                           begin
  1291.                             RMB_Event := true ;
  1292.                             UpDown[2] := Down2 ;
  1293.                             Draw_String(x + (S_CurrentRec[ScrNum]^.X + 
  1294.                                   Length(S_CurrentRec[ScrNum]^.LabelStr) + 1) * 8,
  1295.                                   y + (S_CurrentRec[ScrNum]^.Y) * Spacing, '*') ;
  1296.                           end ;
  1297.                   end ;
  1298.         end;
  1299.  
  1300.      begin
  1301.        Mode := 6 ;
  1302.        MenuOption ;
  1303.        DrawScreen(S_FirstRec[ScrNum]) ;
  1304.        ClrHome ;
  1305.        NewCursor(ScrNum) ;
  1306.  
  1307.        NextRec := Compare ;
  1308.        While NextRec <> nil do
  1309.           begin
  1310.             NextRec^.Match := 0 ;
  1311.             NextRec := NextRec^.Next ;
  1312.           end ;
  1313.  
  1314.        CurRec := DiskRec ;
  1315.        NextRec := Compare ;
  1316.  
  1317.        QuitFlag := false ;
  1318.        While NOT QuitFlag do
  1319.           begin
  1320.             UpdateInfoLine ;
  1321.  
  1322.             RMB_Event := false ;
  1323.             Match := true ;
  1324.             UpDown[1] := Down1 ;
  1325.             UpDown[2] := Down2;
  1326.             Repeat
  1327.               Event_Loop ;
  1328.             Until RMB_Event ;
  1329.  
  1330.             if Match then
  1331.                begin
  1332.                  i := 1 ;
  1333.                  MatchRec := S_FirstRec[ScrNum] ;
  1334.                  While MatchRec <> nil do
  1335.                     if MatchRec = S_CurrentRec[ScrNum] then
  1336.                        MatchRec := nil
  1337.                     else
  1338.                        begin
  1339.                          MatchRec := MatchRec^.Next ;
  1340.                          i := i + 1 ;
  1341.                        end ;
  1342.                  NextRec^.Match := i ;
  1343.                end ;
  1344.  
  1345.             if CurRec <> nil then
  1346.                if CurRec^.Next <> nil then
  1347.                   begin
  1348.                     CurRec := CurRec^.Next ;
  1349.                     NextRec := NextRec^.Next ;
  1350.                   end ;
  1351.           end ;
  1352.        Mode := 2 ;
  1353.        ClrHome ;
  1354.      end ;
  1355.  
  1356. { *************************************************************************
  1357.      Retrieve a disk base database.
  1358. ************************************************************************* }
  1359.   procedure RetrieveFile(DispFlag : boolean) ;
  1360.  
  1361.     var
  1362.        CurRec     : DataPtr ;
  1363.        ScrRec     : array[1..2] of ScrPtr ;
  1364.        TitleStr,
  1365.        TypeStr,
  1366.        SizeStr    : Str255 ;
  1367.        InputStr   : Str255 ;
  1368.        SaveFv     : text ;
  1369.        TempChar   : char ;
  1370.        Location,
  1371.        i,
  1372.        MaxLength,
  1373.        NumFields  : short_integer ;
  1374.        NoMatch    : boolean ;
  1375.        Compare,
  1376.        NextRec    : IntPtr ;
  1377.        SaveIO_Result : short_integer ;
  1378.        Size       : short_integer ;
  1379.        
  1380.      Label
  1381.        1 ;
  1382.        
  1383.      begin
  1384.        IO_Check(false) ;
  1385.        Reset(SaveFv, DefFileDat) ;
  1386.        SaveIO_Result := IO_Result ;
  1387.        if SaveIO_Result <> 0 then GoTo 1 ;
  1388.        NumFields := 0 ;
  1389.        
  1390.        TitleStr := '' ;
  1391.        i := 1 ;
  1392.        
  1393.        Readln(SaveFv, InputStr) ;
  1394.        if InputStr <> 'DataBase' then
  1395.           begin
  1396.             SaveIO_Result := 1 ;
  1397.             GoTo 1 ;
  1398.           end ;
  1399.                
  1400.        if DispFlag then
  1401.           D_DisposeRecs(D_FirstRec[DataNum], D_CurrentRec[DataNum], 
  1402.                         D_LastRec[DataNum]) ;
  1403.           
  1404.        Repeat
  1405.          Readln(SaveFv, InputStr) ;
  1406.          SaveIO_Result := IO_Result ;
  1407.          if SaveIO_Result <> 0 then GoTo 1 ;
  1408.          { Read ^A -- End of Screen Data }
  1409.          Case i of
  1410.             1 : TitleStr := InputStr ;
  1411.             2 : TypeStr  := InputStr ;
  1412.             3 : begin
  1413.                   SizeStr  := InputStr ;
  1414.                   ReadV(SizeStr, Size) ;
  1415.                 end ;
  1416.           end ;
  1417.             
  1418.          i := i + 1 ;
  1419.          if i > 3 then
  1420.             begin
  1421.               AddARec(S_FirstRec[Import],S_CurrentRec[Import],
  1422.                       S_LastRec[Import], S_LastRec[Import], TitleStr, 
  1423.                       0, 0, Size, TypeStr[1], Import ) ;
  1424.               NumFields := NumFields + 1 ;
  1425.               Int_AddARec(C_FirstRec, C_CurRec, C_LastRec, NumFields) ;
  1426.               i := 1 ;
  1427.             end ;
  1428.        Until TitleStr = chr($01) ;
  1429.           
  1430.        NoMatch := false ;
  1431.        ScrRec[ScrNum] := S_FirstRec[ScrNum] ;
  1432.        ScrRec[Import] := S_FirstRec[Import] ;
  1433.        While (ScrRec[ScrNum] <> nil) AND 
  1434.              (ScrRec[Import] <> nil) AND NOT NoMatch do
  1435.           begin
  1436.             if ScrRec[Import]^.LabelStr <> ScrRec[ScrNum]^.LabelStr then 
  1437.                NoMatch := true ;
  1438.  
  1439.             if ScrRec[Import]^.DataType <> ScrRec[ScrNum]^.DataType then 
  1440.                NoMatch := true ;
  1441.  
  1442.             if ScrRec[Import]^.Size <> ScrRec[ScrNum]^.Size then 
  1443.                NoMatch := true ;
  1444.  
  1445.             ScrRec[ScrNum] := ScrRec[ScrNum]^.Next ;
  1446.             ScrRec[Import] := ScrRec[Import]^.Next ;
  1447.           end ;
  1448.                 
  1449.        if ((ScrRec[Import] <> ScrRec[ScrNum]) OR NoMatch) AND
  1450.           (SaveIO_Result = 0) then
  1451.           begin
  1452.             for i := 1 to 2 do
  1453.                 Menu_Disable(InfoMenu, MenuItem.Item[i]) ;
  1454.             FindMatch(S_FirstRec[Import], C_FirstRec ) ;
  1455.             MenuOption ;
  1456.           end ;
  1457.  
  1458.        While NOT EOF(SaveFv) AND NOT FullMemory do
  1459.           begin
  1460.             InputDataRec(DataNum) ;
  1461.             ScrRec[Import] := S_FirstRec[Import] ;
  1462.             CurRec := D_CurrentRec[DataNum] ;
  1463.             NextRec := C_FirstRec ;
  1464.              
  1465.             While ScrRec[Import] <> nil do
  1466.                begin
  1467.                  Readln(SaveFv, InputStr) ;
  1468.                  SaveIO_Result := IO_Result ;
  1469.                  if SaveIO_Result <> 0 then GoTo 1 ;
  1470.                  ScrRec[ScrNum] := S_FirstRec[ScrNum] ;
  1471.                  if NextRec^.Match > 0 then
  1472.                     begin
  1473.                       if NextRec^.Match > 1 then
  1474.                          for i := 2 to NextRec^.Match do
  1475.                              ScrRec[ScrNum] := ScrRec[ScrNum]^.Next ;
  1476.                       MaxLength := ScrRec[ScrNum]^.Size ;
  1477.                       if MaxLength > Length(InputStr) then
  1478.                          MaxLength := Length(InputStr) ;
  1479.                       for i := 1 to MaxLength do
  1480.                           begin
  1481.                             TempChar := InputStr[i] ;
  1482.                             Location := i + ScrRec[ScrNum]^.Offset - 1 ;
  1483.                             ModifyStr(CurRec, Location, TempChar) ;
  1484.                           end ;
  1485.                     end ;
  1486.                  NextRec := NextRec^.Next ;
  1487.                  ScrRec[Import] := ScrRec[Import]^.Next ;
  1488.                end ;
  1489.           end ;
  1490.  
  1491. 1 :     if SaveIO_Result <> 0 then 
  1492.            DiskError(SaveIO_Result) ;
  1493.  
  1494.         if FullMemory then
  1495.            begin
  1496.              AlertStr := '[1][  Insufficient Memory to | ' ;
  1497.              AlertStr := Concat(AlertStr,' |   Load Entire DataBase ]') ;
  1498.              AlertStr := Concat(AlertStr, '[ Continue ]') ;
  1499.              Result := Do_Alert(AlertStr,1) ;
  1500.            end ;
  1501.  
  1502.        Close(SaveFv) ;
  1503.        if SaveIO_Result = 0 then
  1504.           begin
  1505.             D_CurrentRec[DataNum] := D_FirstRec[DataNum] ;
  1506.             RecNo[DataNum] := 1 ;
  1507.  
  1508.             ModifyWName ;
  1509.             UpdateFlag := true ; ;
  1510.             Set_VSlideSize ;
  1511.           end ;
  1512.  
  1513.        if D_FirstRec[DataNum] = nil then
  1514.           CreateDataRec(DataNum) ;
  1515.        DisposeRecs(S_FirstRec[Import], S_CurrentRec[Import], 
  1516.                    S_LastRec[Import]) ;
  1517.        DisposeInt(C_FirstRec, C_CurRec, C_LastRec) ;
  1518.  
  1519.        DrawScreen(S_FirstRec[ScrNum]) ;
  1520.        DrawRecord(D_CurrentRec[DataNum]) ;
  1521.        ShortDraw := true ;
  1522.        IO_Check(true) ;
  1523.      end ;
  1524.  
  1525. { *************************************************************************
  1526.      Retrieve a database from the disk.
  1527. ************************************************************************* }
  1528.   procedure MergeDataBase ;
  1529.  
  1530.      begin
  1531.        if Get_In_File(DefPathDat, DefFileDat) then
  1532.           RetrieveFile(False) ;
  1533.      end ;
  1534.  
  1535.  
  1536. { *************************************************************************
  1537.      Retrieve a database from the disk.
  1538. ************************************************************************* }
  1539.   procedure GetDataBase ;
  1540.  
  1541.      begin
  1542.        if Get_In_File(DefPathDat, DefFileDat) then
  1543.           RetrieveFile(True) ;
  1544.      end ;
  1545.  
  1546. { *************************************************************************
  1547. ************************************************************************* }
  1548.   procedure GetPrtInfo ;
  1549.      
  1550.     var
  1551.        ScrRec    : ScrPtr ;
  1552.        ReportRec : DataPtr ;
  1553.        PrintFv   : text ;
  1554.        i, 
  1555.        Location  : short_integer ;
  1556.        TempChar  : char ;
  1557.        SaveIO_Result : short_integer ;
  1558.        
  1559.      Label
  1560.        1 ;
  1561.        
  1562.      begin
  1563.        IO_Check(false) ;
  1564.        if Get_In_File(DefPathPrt, DefFilePrt) then
  1565.           begin
  1566.             Reset(PrintFv, DefFilePrt) ;
  1567.             SaveIO_Result := IO_Result ;
  1568.             if SaveIO_Result <> 0 then GoTo 1 ;
  1569.             
  1570.             Readln(PrintFv, FormatStr) ;
  1571.             SaveIO_Result := IO_Result ;
  1572.             if SaveIO_Result <> 0 then GoTo 1 ;
  1573.             if FormatStr <> 'ReportDesign' then
  1574.                begin
  1575.                  SaveIO_Result := 1 ;
  1576.                  GoTo 1 ;
  1577.                end ;
  1578.                
  1579.             ReportRec := D_FirstRec[Report] ;
  1580.             ScrRec := S_FirstRec[Report] ;
  1581.             While ScrRec <> nil do
  1582.               begin
  1583.                 Readln(PrintFv, FormatStr) ;
  1584.                 SaveIO_Result := IO_Result ;
  1585.                 if SaveIO_Result <> 0 then GoTo 1 ;
  1586.                 for i := 1 to Length(FormatStr) do
  1587.                     begin
  1588.                       TempChar := FormatStr[i] ;
  1589.                       Location := i + ScrRec^.Offset - 1 ;
  1590.                       ModifyStr(ReportRec, Location, TempChar) ;
  1591.                     end ;
  1592.                 ScrRec := ScrRec^.Next ;
  1593.               end ;
  1594.               
  1595.             Readln(PrintFv, P_Mode) ;
  1596.             SaveIO_Result := IO_Result ;
  1597.             if SaveIO_Result <> 0 then GoTo 1 ;
  1598.             Readln(PrintFv, RepWidth) ;
  1599.             SaveIO_Result := IO_Result ;
  1600.             if SaveIO_Result <> 0 then GoTo 1 ;
  1601.             for i := 1 to 4 do
  1602.                 begin
  1603.                   Readln(PrintFv, PrtInit[i]) ;
  1604.                   SaveIO_Result := IO_Result ;
  1605.                   if SaveIO_Result <> 0 then GoTo 1 ;
  1606.                 end ;
  1607.                 
  1608.             Readln(PrintFv, RepLine) ;
  1609.             SaveIO_Result := IO_Result ;
  1610.             if SaveIO_Result <> 0 then GoTo 1 ;
  1611.              
  1612.             Readln(PrintFv, LabSpace[1]) ;
  1613.             SaveIO_Result := IO_Result ;
  1614.             if SaveIO_Result <> 0 then GoTo 1 ;
  1615.             
  1616.             Readln(PrintFv, LabLine) ;
  1617.             SaveIO_Result := IO_Result ;
  1618.             if SaveIO_Result <> 0 then GoTo 1 ;
  1619.              
  1620.             Readln(PrintFv, LabSpace[2]) ;
  1621.             SaveIO_Result := IO_Result ;
  1622.             if SaveIO_Result <> 0 then GoTo 1 ;
  1623.             R_EditFlag := false ;
  1624.             R_LoadFlag := true ;
  1625.             
  1626. 1 :         if SaveIO_Result <> 0 then   
  1627.                DiskError(SaveIO_Result) ;
  1628.             Close(PrintFv) ;
  1629.           end ;
  1630.        IO_Check(true) ;
  1631.      end ;
  1632.  
  1633. { *************************************************************************
  1634. ************************************************************************* }
  1635.   procedure SavePrtInfo ;
  1636.      
  1637.     var
  1638.        i         : short_integer ;
  1639.        ScrRec    : ScrPtr ;
  1640.        ReportRec : DataPtr ;
  1641.        PrintFv   : text ;
  1642.        SaveIO_Result : short_integer ;
  1643.        
  1644.      Label
  1645.        1 ;
  1646.        
  1647.      begin
  1648.        IO_Check(FALSE) ;
  1649.        if Get_In_File(DefPathPrt, DefFilePrt) then
  1650.           begin
  1651.             Rewrite(PrintFv, DefFilePrt) ;
  1652.             SaveIO_Result := IO_Result ;
  1653.             if SaveIO_Result <> 0 then GoTo 1 ;
  1654.  
  1655.             Writeln(PrintFv, 'ReportDesign') ;
  1656.             SaveIO_Result := IO_Result ;
  1657.             if SaveIO_Result <> 0 then GoTo 1 ;
  1658.  
  1659.             ReportRec := D_FirstRec[Report] ;
  1660.             ScrRec := S_FirstRec[Report] ;
  1661.             While ScrRec <> nil do
  1662.               begin
  1663.                 GetStr(ReportRec,FormatStr,ScrRec^.Offset,ScrRec^.Size ) ;
  1664.                 Writeln(PrintFv, FormatStr) ;
  1665.                 SaveIO_Result := IO_Result ;
  1666.                 if SaveIO_Result <> 0 then GoTo 1 ;
  1667.                 ScrRec := ScrRec^.Next ;
  1668.               end ;
  1669.               
  1670.             Writeln(PrintFv, P_Mode) ;
  1671.             SaveIO_Result := IO_Result ;
  1672.             if SaveIO_Result <> 0 then GoTo 1 ;
  1673.  
  1674.             Writeln(PrintFv, RepWidth) ;
  1675.             SaveIO_Result := IO_Result ;
  1676.             if SaveIO_Result <> 0 then GoTo 1 ;
  1677.  
  1678.             for i := 1 to 4 do
  1679.                 begin
  1680.                   Writeln(PrintFv, PrtInit[i]) ;
  1681.                   SaveIO_Result := IO_Result ;
  1682.                   if SaveIO_Result <> 0 then GoTo 1 ;
  1683.                 end ;
  1684.                   
  1685.             Writeln(PrintFv, RepLine) ;
  1686.             SaveIO_Result := IO_Result ;
  1687.             if SaveIO_Result <> 0 then GoTo 1 ;
  1688.             Writeln(PrintFv, LabSpace[1]) ;
  1689.             SaveIO_Result := IO_Result ;
  1690.             if SaveIO_Result <> 0 then GoTo 1 ;
  1691.             Writeln(PrintFv, LabLine) ;
  1692.             SaveIO_Result := IO_Result ;
  1693.             if SaveIO_Result <> 0 then GoTo 1 ;
  1694.             Writeln(PrintFv, LabSpace[2]) ;
  1695.             SaveIO_Result := IO_Result ;
  1696.             
  1697. 1 :         if SaveIO_Result <> 0 then 
  1698.                DiskError(SaveIO_Result) ;
  1699.             
  1700.             R_EditFlag := false ;
  1701.             R_LoadFlag := true ;
  1702.             Close(PrintFv) ;
  1703.           end ;
  1704.        IO_Check(true) ;
  1705.      end ;
  1706.  
  1707. BEGIN
  1708. END .
  1709.